"""Lambda 表达式 IR 节点"""

import ast
from dataclasses import dataclass, field
from typing import List, Optional, Dict, Iterator, cast

from mcpy.ir.expressions.base import IRExpr
from mcpy.ir.base import IRNode, Parameter
from mcpy.symbol_meta import Symbol


@dataclass
class IRLambda(IRExpr):
    """Lambda 表达式 IR 节点

    表示 Python 的 lambda 表达式：
        lambda x, y: x + y
    """

    # 核心属性
    params: List[Parameter] = field(default_factory=list)
    body: Optional[IRExpr] = field(default=None)
    return_type: Optional[str] = field(default=None)

    # 闭包相关
    captured_vars: List[str] = field(default_factory=list)
    captured_var_types: Dict[str, str] = field(default_factory=dict)

    # 代码生成相关
    usage_mode: str = field(default="extension")  # "extension" | "cpp_lambda"
    functor_name: str = field(default="")

    # 节点类型
    node_type: str = "lambda"

    def creates_scope(self) -> bool:
        """Lambda 创建作用域"""
        return True

    def get_child_nodes(self) -> Iterator[IRNode]:
        """获取子节点"""
        for param in self.params:
            yield param
        if self.body:
            yield self.body

    def get_local_symbols(self) -> Iterator[Symbol]:
        """获取 lambda 的本地符号（参数）

        Returns:
            本地符号的迭代器
        """

        # Lambda 的本地符号只有参数
        for param in self.params:
            yield param.get_symbol()

    def build_from_ast(self, node: ast.Lambda) -> None:
        """从 AST Lambda 节点构建 IR

        Args:
            node: ast.Lambda 节点
        """
        super().build_from_ast(node)

        # 保存列偏移信息（用于生成稳定的 functor 名称）
        if hasattr(node, 'col_offset'):
            self.set_extension_param("col_offset", node.col_offset)

        # 提取参数
        # 注意：标准 Python lambda 不支持默认参数和关键字参数，
        # 但我们可以从 AST 中提取信息以支持扩展语法
        # node.args.args 中的 arg.annotation 对于 lambda 总是 None
        self.params = []
        
        # 获取默认值列表（从后往前对应参数）
        defaults = list(node.args.defaults) if hasattr(node.args, 'defaults') else []
        num_defaults = len(defaults)
        num_args = len(node.args.args)
        
        for i, arg in enumerate(node.args.args):
            # 计算是否有默认值（默认值从后往前对应）
            default_index = i - (num_args - num_defaults)
            default_value = None
            if default_index >= 0:
                # 有默认值，需要构建 IR 表达式
                from mcpy.ir.expressions.base import build_expr_from_ast
                default_ast = defaults[default_index]
                default_value = build_expr_from_ast(default_ast, parent=self)
            
            param = Parameter(
                name=arg.arg,
                type_annotation="",  # Lambda 参数无类型注解
                default_value=default_value,
                parent=self,
            )
            if hasattr(self, "source_line"):
                param.source_line = self.source_line
            self.params.append(param)

        # 提取 lambda 体（必须是表达式）
        from mcpy.ir.expressions.base import build_expr_from_ast, IRExpr as IRExprType

        body_node = build_expr_from_ast(node.body, parent=self)
        self.body = cast(IRExprType, body_node) if body_node else None

    def __repr__(self) -> str:
        """字符串表示"""
        param_str = ", ".join([p.name for p in self.params])
        body_str = repr(self.body) if self.body else "None"
        return (
            f"IRLambda(params=[{param_str}], body={body_str}, mode={self.usage_mode})"
        )
